import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:jimo_base_service/CacheService.dart';
class NetworkService{
  static late String currentBaseUrl;
  static late Dio _dio;
  static setup({required String baseUrl}) async {
    if(!baseUrl.endsWith("/")){
      currentBaseUrl="$baseUrl/";
    }else{
      currentBaseUrl=baseUrl;
    }
    _dio=Dio();
  }
  static Future<ResponseData> post({required String url,required Map<String,dynamic> map,useFormData=true}) async {
    var token=await CacheService.getString("user_token");
    print('\x1B[94m |————————————————请求头部———————————————|\x1B[0m');
    print("token:$token");
    print('\x1B[94m |————————————————请求头部———————————————|\x1B[0m');
    print('\x1B[92m |————————————————请求参数———————————————|\x1B[0m');
    print('\x1B[92m POST:$currentBaseUrl$url\x1B[0m');
    print('\x1B[92m${json.encode(map)}\x1B[0m');
    print('\x1B[92m |————————————————请求参数———————————————|\x1B[0m');
    try{
       var res=(await _dio.post("$currentBaseUrl$url",options: Options(contentType: "application/json",headers: {
         "token":token,
       }),data:useFormData?FormData.fromMap(map):map));
       ResponseData response=_wrapperResponseHandler(ResponseData.fromJson(res.data));
       print('\x1B[92m 请求成功\x1B[0m');
       print(json.encode(response.data));
       print('\x1B[92m 请求成功\x1B[0m');
       return response;
    }catch(e){
      if(e is DioError){
        print('\x1B[91m 请求失败  失败类型:${e.type.name},失败原因：${e.message}\x1B[0m');
        throw RequestError(code: 0, message: e.type.name);
      }else if(e is RequestError){
        print('\x1B[91m 服务器返回错误  错误吗:${e.code},错误原因：${e.message}\x1B[0m');
        rethrow;
      }else{
        print("\x1B[91m |————————————————未知错误：\x1B[0m");
        print(e);
        print("\x1B[91m |——————————————————————————————————————\x1B[0m");
        throw RequestError(code: 0, message: e.toString());
      }
    }
  }
  static ResponseData _wrapperResponseHandler(ResponseData responseData) {
    if (responseData.code != 200) {
      throw RequestError(code: responseData.code!, message: responseData.message!);
    }
    return responseData;
  }
  static Future<Response> postFile({
    required String url,
    dynamic data,
  }) async {
    return await _dio.post("$currentBaseUrl$url",data:data,options:Options(headers: {
      "token":await CacheService.getString("user_token"),
    },responseType: ResponseType.bytes));
  }
}
class RequestError{
  String message;
  int code;
  RequestError({required this.code,required this.message});
}
class ResponseData {
  final int? code;
  final String? message;
  final dynamic data;
  ResponseData({this.code, this.message, this.data});
  ResponseData.fromJson(Map json): code = toInt(json['code']), message = json['message'] as String?, data = json['data'];
  Map tojson() {
    return {'code': code, 'message': message, 'data': data};
  }
  @override
  String toString() {
    return tojson().toString();
  }
  T? getTypedData<T>(T? Function(Map? map) creator) {
    var map = data as Map<String, dynamic>?;
    if (map == null) {
      return null;
    }
    return creator(map);
  }
  List<T>? getTypedList<T>(T? Function(Map? map) creator) {
    List? list = data as List?;
    return toList(list, creator);
  }
  static List<T>? toList<T>(List? mapList, T? Function(Map? map) creator) {
    if (mapList == null) {
      return null;
    }
    List<T> ret = [];
    for (var m in mapList) {
      if (m == null) continue;
      var t = creator(m);
      if (t != null) {
        ret.add(t);
      }
    }
    return ret;
  }
  static int? toInt(dynamic data) {
    try {
      if (data == null) return null;
      if (data.runtimeType == int) return data;
      if (data.runtimeType == double) return (data as double).toInt();
      if (data.runtimeType == String) {
        String? string = (data as String?)?.trim();
        if (string == null || string.isEmpty) return null;
        return int.tryParse(string);
      }
    } catch (e, s) {
      print(e.toString());
      print(s.toString());
    }

    return null;
  }
}